package com.mxpio.erp.oa.service.impl;

import com.google.common.collect.Lists;
import com.mxpio.erp.common.enums.BizExceptionEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.model.request.BpmnSubmitRequest;
import com.mxpio.erp.common.oa.entity.OaRewardPunishment;
import com.mxpio.erp.common.oa.service.OaRewardPunishmentService;
import com.mxpio.erp.common.util.AssertUtil;
import com.mxpio.erp.common.util.CloneUtil;
import com.mxpio.erp.common.util.JacksonMapUtils;
import com.mxpioframework.camunda.service.BpmnFlowService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.PojoDictParseService;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

;

@Service
public class OaRewardPunishmentServiceImpl extends BaseServiceImpl<OaRewardPunishment> implements OaRewardPunishmentService {

        @Resource
        private BpmnFlowService bpmnFlowService;

        @Resource
        private PojoDictParseService dictService;

        @Override
        @Transactional(rollbackFor = Exception.class)
        public OaRewardPunishment doSave(OaRewardPunishment oaRewardPunishment) {
            oaRewardPunishment.setBpmnStatus(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode());
            this.save(oaRewardPunishment);

            return oaRewardPunishment;
        }

        @Override
        @Transactional
        public OaRewardPunishment submit(BpmnSubmitRequest request) {

            AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

            OaRewardPunishment oaRewardPunishmentOrder = this.getById(OaRewardPunishment.class, request.getBizNo());

            AssertUtil.notNull(oaRewardPunishmentOrder, BizExceptionEnums.ORDER_NOT_FOUND);

            //1. 开启工作流
            OaRewardPunishment oaRewardPunishment = parseDict(oaRewardPunishmentOrder);
            Map<String, Object> workFlowParam = JacksonMapUtils.convertObjectToMap(oaRewardPunishment);
            ProcessInstance processInstance = bpmnFlowService.startWithFormByKey(request.getKey(), SecurityUtils.getLoginUsername(), request.getBusinessKey(),workFlowParam);
            //2. 更新工单 TODO 这里应该使用数据库乐观锁防止并发修改,还不清楚jpa如何使用乐观锁
            oaRewardPunishmentOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode());
            oaRewardPunishmentOrder.setProcessInstanceId(processInstance.getId());
            this.update(oaRewardPunishmentOrder);

            return oaRewardPunishmentOrder;
        }

        @Override
        @Transactional
        public OaRewardPunishment audit(BpmnSubmitRequest request) {

            AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

            OaRewardPunishment oaRewardPunishmentOrder = this.getById(OaRewardPunishment.class, request.getBizNo());

            AssertUtil.notNull(oaRewardPunishmentOrder, BizExceptionEnums.ORDER_NOT_FOUND);

            List<String> passStatus = Lists.newArrayList(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode(),
                OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());

            AssertUtil.notNull(passStatus.contains(request.getBpmnStatus()),BizExceptionEnums.ORDER_AUDIT_STATUS_ERROR);

            if (request.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())) {
                 oaRewardPunishmentOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
             }else{
                 oaRewardPunishmentOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());
             }

             this.update(oaRewardPunishmentOrder);

             return oaRewardPunishmentOrder;
            }

        private OaRewardPunishment parseDict(OaRewardPunishment OaRewardPunishmentOrder) {
            OaRewardPunishment cloneOaRewardPunishment = CloneUtil.deepClone(OaRewardPunishmentOrder, OaRewardPunishment.class);
            Result<OaRewardPunishment> result = Result.OK(cloneOaRewardPunishment);
            dictService.parseDictResult(result);
            return result.getResult();
        }
}